package com.alex.jbpm.apply;

import java.util.Iterator;
import java.util.List;

import junit.framework.TestCase;

import org.hibernate.Session;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.graph.def.Node;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.def.Transition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.taskmgmt.exe.TaskInstance;

import com.alex.jbpm.HibernateUtils;
import com.alex.jbpm.domain.Document;


public class ApplyTest extends TestCase {
	
	static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();
	
	/**
	 * 部署流程
	 */
	public void testDeployProcessDefinition() {

		ProcessDefinition processDefinition = ProcessDefinition
				.parseXmlResource("apply/apply_2.xml");

		// context对象类似于hibernate session对象的功能
		JbpmContext context = jbpmConfiguration.createJbpmContext();

		try {
			context.deployProcessDefinition(processDefinition);
		} finally {
			// context对象需要关闭
			context.close();
		}

	}
	
	/**
	 * 创建公文
	 */
	public void testCreateDocumentAndBindProcess() {

		Session session = HibernateUtils.getSession();

		try {
			session.beginTransaction();

			Document doc = new Document();
			doc.setTitle("资助申请——3");
			doc.setContent("申请内容——3");
			doc.setCreator("3");
			session.save(doc);

			JbpmContext context = jbpmConfiguration.createJbpmContext();
			context.setSessionFactory(HibernateUtils.getSessionFactory());
			
			// 从数据库中加载ProcessDefinition对象
			ProcessDefinition definition = context.getGraphSession()
					.findLatestProcessDefinition("applyProcess_2");
			
			// 从流程中创建一个流程实例
			ProcessInstance processInstance = new ProcessInstance(definition);

			// 存储流程实例
			context.save(processInstance);
			
			// 绑定流程实例到公文
			doc.setProcessIntanceId(processInstance.getId());

			// 绑定公文到流程实例(ContextInstance相当于一个变量的容器)
			processInstance.getContextInstance().createVariable("documentId",
					doc.getId());
			
			session.getTransaction().commit();
			
			context.close();
		} catch (Exception e) {
			session.getTransaction().rollback();
			e.printStackTrace();
		} finally {
			HibernateUtils.closeSession(session);
		}
	}
	
	/**
	 * 测试学校的提交
	 */
	public void testSubmit(){
		JbpmContext context = jbpmConfiguration.createJbpmContext();
		context.setSessionFactory(HibernateUtils.getSessionFactory());

		Document doc = (Document) context.getSession().load(Document.class, 47);

		ProcessInstance processInstance = context.getProcessInstance(doc
				.getProcessIntanceId());
		processInstance.signal();
		context.close();
	}
	
	/**
	 * 测试获取所有处于县级的document
	 */
	public void testGetAllDoucProcessInCounty(){
		getAllDocByLevel("xian");
	}
	
	/**
	 * 测试获取所有处于县级的document
	 */
	public void testGetAllDoucProcessInCity(){
		getAllDocByLevel("shi");
	}
	
	public void testGetAllDoucProcessInProvince(){
		getAllDocByLevel("sheng");
	}
	
	/**
	 * 获取不同等级的申请表单
	 * @param actorLevel
	 */
	private void getAllDocByLevel(String actorLevel) {
		JbpmContext context = jbpmConfiguration.createJbpmContext();
		context.setSessionFactory(HibernateUtils.getSessionFactory());
		
		@SuppressWarnings("unchecked")
		List<Document> docs = HibernateUtils.getSession().createCriteria(Document.class).list();
		for(Document doc : docs){
			ProcessInstance processInstance = context.getProcessInstance(doc
					.getProcessIntanceId());
			
			@SuppressWarnings("unchecked")
			Iterator<TaskInstance> it = processInstance.getTaskMgmtInstance().getTaskInstances().iterator();
			while(it.hasNext()){
				TaskInstance ti = it.next();
				if(actorLevel.equals(ti.getActorId()) && !ti.hasEnded()){
					System.out.println(doc.getId());
				}
			}
		}
	}
	
	/**
	 * 测试获取下一节点流程路线及节点的方法
	 */
	@SuppressWarnings("unchecked")
	public void testShowNextTransitionAndNode(){
		JbpmContext context = jbpmConfiguration.createJbpmContext();
		context.setSessionFactory(HibernateUtils.getSessionFactory());
		
		Document doc = (Document) context.getSession().load(Document.class, 25);

		ProcessInstance processInstance = context.getProcessInstance(doc
				.getProcessIntanceId());
		Node node = processInstance.getRootToken().getNode();
		System.out.println("流程定义名称："+processInstance.getProcessDefinition().getName());
		System.out.println("当前节点名称："+node.getName());
		System.out.println("可选择的流转路径：");
		for(Transition t : (List<Transition>)node.getLeavingTransitionsList()){
			System.out.println("路径名称："+t.getName());
			System.out.println("路径终点："+t.getTo().getName());
			System.out.println("-----------------------------------");
		}
	}
	
	/**
	 * 测试县级审批通过
	 */
	public void testCountyProcessApprove(){
		applyTask(47, "通过");
	}
	
	/**
	 * 测试流程实例使用已经结束
	 */
	public void testProcessEnd(){
		JbpmContext context = jbpmConfiguration.createJbpmContext();
		context.setSessionFactory(HibernateUtils.getSessionFactory());

		Document doc = (Document) context.getSession().load(Document.class, 34);
		ProcessInstance processInstance = context.getProcessInstance(doc
				.getProcessIntanceId());
		System.out.println(processInstance.hasEnded());
	}
	
	/**
	 * 根据审批结果更新申请表单
	 * @param docId
	 * @param approved
	 */
	@SuppressWarnings("unchecked")
	private void applyTask(int docId,String approved){
		JbpmContext context = jbpmConfiguration.createJbpmContext();
		context.setSessionFactory(HibernateUtils.getSessionFactory());

		Document doc = (Document) context.getSession().load(Document.class, docId);
		ProcessInstance processInstance = context.getProcessInstance(doc
				.getProcessIntanceId());
		String actorLevel = processInstance.getContextInstance().getVariable("actorLevel").toString();
		
		Node node = processInstance.getRootToken().getNode();
		List<Transition> trans = (List<Transition>)node.getLeavingTransitionsList();
		Iterator<TaskInstance> it = processInstance.getTaskMgmtInstance().getTaskInstances().iterator();
		while(it.hasNext()){
			TaskInstance ti = it.next();
			if(actorLevel.equals(ti.getActorId())){
				String transitionName = null;
				for(Transition t : trans){
					if(t.getName().indexOf(approved) != -1){
						transitionName = t.getName();
					}
				}
				if(transitionName == null){
					transitionName = trans.get(0).getName();
				}
				ti.end(transitionName);
				break;
			}
		}
		String examineState = actorLevel.concat(" 审批: ").concat(approved);
		doc.setExamineState(processInstance.hasEnded() ? examineState.concat("，审批结束") : examineState);
		
		context.getSession().save(doc);
		
		context.close();
	}
	
	/**
	 * 测试县级审批不通过
	 */
	
	public void testCountyProcessDisApprove(){
		applyTask(34, "不通过");
	}
	
	/**
	 * 测试市级审批通过
	 */
	public void testCityProcessApprove(){
		applyTask(35, "通过");
	}
	
	/**
	 * 测试市级审批不通过
	 */
	public void testCityProcessDisapprove(){
		applyTask(41, "不通过");
	}
}
